package email.ejb;

import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import email.entity.AuthenticatorSMTP;
import email.entity.Email;
import email.entity.Protocolo;

@Singleton
public class EmailBean {
	
	// 1 - propriedade para o envio de email
	private int port = 25; //portas padrao: smtp=465; tls=25
	private String host = "BNAMAIL.lda.bna.ao"; //"smtp.gmail.com";
	private String from = "dma@bna.ao";
	private boolean auth = false;
	private String username = "matt@example.com";
	private String password = "secretpw";
	private Protocolo protocolo = Protocolo.SMTP;
	private boolean debug = true;
	
	@Resource(name = "mail/bnamail")
	private Session mailSession;
	
	@Schedule(minute="*/5", hour="*")
	public void enviarEmailSimple() throws AddressException, MessagingException {
		// 2 - configuracao do objecto Properties com as definicoes do protocolo SMTP
		Properties props = new Properties();
		props.put("mail.smtp.host", host);
		props.put("mail.smtp.port", port);
		
		switch (protocolo) {
		    case SMTPS:
		        props.put("mail.smtp.ssl.enable", true);
		        break;
		    case TLS:
		        props.put("mail.smtp.starttls.enable", true);
		        break;
		}
		/*
		InitialContext initCtx;
		try {
			initCtx = new InitialContext();
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		Context envCtx;
		try {
			envCtx = (Context) initCtx.lookup("java:comp/env");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		
		// 3 - criar uma sessao que usa o Properties e o authenticator; 
		//	   se a autenticacao nao for necessaria, o argumento eh nulo.
		
		//Session sessao = Session.getInstance(props);
		Session sessao;
		try {
			sessao = (Session) envCtx.lookup("mail/bnamail");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		sessao.setDebug(debug);*/ // <=> props.put("mail.debug", "true");
		
		// 4 - criar a mensagem e envia-la
		MimeMessage email = new MimeMessage(mailSession);
		email.setFrom(new InternetAddress("mcrosa@lda.bna.ao"));
		email.setRecipient(Message.RecipientType.TO, new InternetAddress("dfancone@lda.bna.ao"));
		
	    InternetAddress[] normais = this.montarDestinatarios("mcrosa@lda.bna.ao;dfancone@lda.bna.ao");
	    if (normais != null) {
			email.setRecipients(Message.RecipientType.CC, normais);
		}
		
	    InternetAddress[] ocultos = this.montarDestinatarios("mcrosa@lda.bna.ao;dfancone@lda.bna.ao");
	    if (ocultos != null) {
			email.setRecipients(Message.RecipientType.BCC, ocultos);
		}
	    
	    email.setSubject("4ªfeira");
	    //email.setHeader(name, value);
	    email.setHeader("X-Mailer", "JavaMail");
	    email.setSentDate(new Date());
	    email.setText("HORA DO PAPUCHO!\n\nDepois do almoço fazer a ceia...."); //bean.getMensagem());
	    Transport.send(email);
	    System.out.println("email enviado com sucesso...");
		
	}
	
	public void enviarEmailSimple2(Email bean) throws AddressException, MessagingException {
		// 2 - configuracao do objecto Properties com as definicoes do protocolo SMTP
		Properties props = new Properties();
		props.put("mail.smtp.host", host);
		props.put("mail.smtp.port", port);
		
		switch (protocolo) {
		    case SMTPS:
		        props.put("mail.smtp.ssl.enable", true);
		        break;
		    case TLS:
		        props.put("mail.smtp.starttls.enable", true);
		        break;
		}
		
		// 3 - criar uma sessao que usa o Properties e o authenticator; 
		//	   se a autenticacao nao for necessaria, o argumento eh nulo.
		Session sessao = Session.getInstance(props);
		sessao.setDebug(debug); // <=> props.put("mail.debug", "true");
		
		// 4 - criar a mensagem e envia-la
		MimeMessage email = new MimeMessage(sessao);
		email.setFrom(new InternetAddress(bean.getEmissor()));
		email.setRecipient(Message.RecipientType.TO, new InternetAddress(bean.getDestinatario()));
		
	    InternetAddress[] normais = this.montarDestinatarios(bean.getDestinatarioCC());
	    if (normais != null) {
			email.setRecipients(Message.RecipientType.CC, normais);
		}
		
	    InternetAddress[] ocultos = this.montarDestinatarios(bean.getDestinatarioBCC());
	    if (ocultos != null) {
			email.setRecipients(Message.RecipientType.BCC, ocultos);
		}
	    
	    email.setSubject(bean.getAssunto());
	    //message.setHeader(name, value)
	    email.setSentDate(new Date());
	    email.setText("essa eh boa...."); //bean.getMensagem());
	    Transport.send(email);
		
	}
	
	public void enviarEmailAutenticado(Email bean) throws AddressException, MessagingException {
		// 2 - configuracao do objecto Properties com as definicoes do protocolo SMTP
		Properties props = new Properties();
		props.put("mail.smtp.host", host);
		props.put("mail.smtp.port", port);
		
		switch (protocolo) {
		    case SMTPS:
		        props.put("mail.smtp.ssl.enable", true);
		        break;
		    case TLS:
		        props.put("mail.smtp.starttls.enable", true);
		        break;
		}		
	    //------------------------------------------------------------------------------------------------------------------
		// 3 - se a authenticacao for necessaria, defini-la
		Authenticator authenticator = null;
		if (auth) {
		    props.put("mail.smtp.auth", true);
		    this.username = bean.getEmissor();
		    this.password = "Neilamstrong@";
		    authenticator = new AuthenticatorSMTP(this.username, this.password);
		}
	    //------------------------------------------------------------------------------------------------------------------
		// 4 - criar uma sessao que usa o Properties e o authenticator; 
		//	   se a autenticacao nao for necessaria, o argumento eh nulo.
		Session sessao = Session.getInstance(props, authenticator);
		sessao.setDebug(debug); // => props.put("mail.debug", "true");
	    //------------------------------------------------------------------------------------------------------------------
		// 5 - criar a mensagem e envia-la
		MimeMessage email = new MimeMessage(sessao);
		email.setFrom(new InternetAddress(bean.getEmissor()));
		email.setRecipient(Message.RecipientType.TO, new InternetAddress(bean.getDestinatario()));
		
	    InternetAddress[] normais = this.montarDestinatarios(bean.getDestinatarioCC());
	    if (normais != null) {
			email.setRecipients(Message.RecipientType.CC, normais);
		}
		
	    InternetAddress[] ocultos = this.montarDestinatarios(bean.getDestinatarioBCC());
	    if (ocultos != null) {
			email.setRecipients(Message.RecipientType.BCC, ocultos);
		}
	    
	    email.setSubject(bean.getAssunto());
	    //message.setHeader(name, value)
	    email.setSentDate(new Date());
	    //email.setText(bean.getMensagem());
	    //Transport.send(email);
	    //------------------------------------------------------------------------------------------------------------------
	    //------------------------------------------------------------------------------------------------------------------
	    // preparando o corpo do e-mail
	    // 5.1 - Create a MimeMultipart instance with an alternative sub-type. A mulit-part message consists of multiple parts, in this case an HTML and a text message (other possible parts are file attachments). The alternative sub-type indicates that the multiple message parts are alternative versions of the same content.
	    Multipart partesEmail = new MimeMultipart("alternative");
	    
	    // Create a MimeBodyPart instance to contain the text body part
	    MimeBodyPart corpoEmail = new MimeBodyPart();
	    corpoEmail.setContent(bean.getMensagem(), "text/html");
	    partesEmail.addBodyPart(corpoEmail);
	    //------------------------------------------------------------------------------------------------------------------
	    // anexando arquivos
	    // 5.2 - Create a MimeBodyPart instance to contain the HTML body part. Order is important, the preferred format of an alternative multi-part message should be added last.
	    if (bean.getAnexos() != null && bean.getAnexos().trim().length() > 0) {
		    MimeBodyPart anexoEmail = new MimeBodyPart();
		    FileDataSource arquivoAnexo = new FileDataSource(bean.getAnexos());
		    anexoEmail.setDataHandler(new DataHandler(arquivoAnexo));
		    anexoEmail.setFileName(arquivoAnexo.getName());
		    partesEmail.addBodyPart(anexoEmail);
		}
	    //------------------------------------------------------------------------------------------------------------------
	    // 5.3 - Add both MimeBodyPart instances to the MimeMultipart instance and set the MimeMultipart instance as the MimeMessage. 
	    email.setContent(partesEmail);
	    Transport.send(email);
	    //------------------------------------------------------------------------------------------------------------------
		
	}
	
	private InternetAddress[] montarDestinatarios(String destinatarios) throws AddressException {
		InternetAddress[] emails = null;
		if (destinatarios != null && destinatarios.trim().length() > 0) {
			String[] lista = destinatarios.split(";");
			emails = new InternetAddress[lista.length];
			for (int i = 0; i < lista.length; i++) {
				emails[i] = new InternetAddress(lista[i]);
			}
		}
		return emails;		
	}
}
